﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Linq;
using System.Text;
using Urs.Admin.Models.Stores;
using Urs.Core;
using Urs.Data.Domain.Configuration;
using Urs.Data.Domain.Stores;
using Urs.Framework.Controllers;
using Urs.Framework.Extensions;
using Urs.Framework.Kendoui;
using Urs.Services.ExportImport;
using Urs.Services.Localization;
using Urs.Services.Logging;
using Urs.Services.Media;
using Urs.Services.Security;
using Urs.Services.Stores;
using Urs.Services.Users;
using Urs.Admin.Models.Common;

namespace Urs.Admin.Controllers
{
    [AdminAuthorize]
    public partial class BrandController : BaseAdminController
    {
        #region Fields

        private readonly ICategoryService _categoryService;
        private readonly IBrandService _brandService;
        private readonly IGoodsService _goodsService;
        private readonly IUserService _userService;
        private readonly IPictureService _pictureService;
        private readonly ILocalizationService _localizationService;
        private readonly IImportManager _importManager;
        private readonly IExportManager _exportManager;
        private readonly IWorkContext _workContext;
        private readonly IActivityLogService _activityLogService;
        private readonly IPermissionService _permissionService;
        private readonly AdminAreaSettings _adminAreaSettings;
        private readonly StoreSettings _storeSettings;

        #endregion

        #region Constructors

        public BrandController(ICategoryService categoryService,
            IBrandService brandService,
            IGoodsService goodsService,
            IUserService userService, IPictureService pictureService,
             ILocalizationService localizationService, IImportManager importManager,
            IExportManager exportManager, IWorkContext workContext,
            IActivityLogService activityLogService,
            IPermissionService permissionService,
            AdminAreaSettings adminAreaSettings, StoreSettings storeSettings)
        {
            this._categoryService = categoryService;
            this._brandService = brandService;
            this._goodsService = goodsService;
            this._userService = userService;
            this._pictureService = pictureService;
            this._localizationService = localizationService;
            this._importManager = importManager;
            this._exportManager = exportManager;
            this._workContext = workContext;
            this._activityLogService = activityLogService;
            this._permissionService = permissionService;
            this._adminAreaSettings = adminAreaSettings;
            this._storeSettings = storeSettings;
        }

        #endregion

        #region List

        public IActionResult Index()
        {
            return RedirectToAction("List");
        }

        public IActionResult List()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageBrands))
                return HttpUnauthorized();

            var model = new BrandListModel();

            return View(model);
        }

        [HttpPost]
        public IActionResult List(PageRequest command, BrandListModel model)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageBrands))
                return HttpUnauthorized();

            var brands = _brandService.GetAll(model.SearchName,
                command.Page - 1, command.Limit, true);
            var result = new ResponseResult
            {
                data = brands.Select(x => x.ToModel<BrandModel>()),
                count = brands.TotalCount
            };
            return Json(result);
        }

        #endregion

        #region Create / Edit / Delete

        public IActionResult Create()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageBrands))
                return HttpUnauthorized();

            var model = new BrandModel();
            //default values
            model.PageSize = 20;
            model.Published = true;

            return View(model);
        }

        [HttpPost]
        public IActionResult Create(BrandModel model, bool continueEditing)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageBrands))
                return HttpUnauthorized();

            if (ModelState.IsValid)
            {
                var brand = model.ToEntity<Brand>();
                brand.CreateTime = DateTime.Now;
                brand.UpdateTime = DateTime.Now;
                _brandService.Insert(brand);
                //activity log
                _activityLogService.InsertActivity("AddNewBrand", _localizationService.GetResource("ActivityLog.AddNewBrand"), brand.Name);

                return continueEditing ? RedirectToAction("Edit", new { id = brand.Id }) : RedirectToAction("List");
            }

            return View(model);
        }

        public IActionResult Edit(int id)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageBrands))
                return HttpUnauthorized();

            var brand = _brandService.GetById(id);
            if (brand == null || brand.Deleted)
            {
                var model = new BrandModel();
                return View(model);
            }
            else
            {
                var model = brand.ToModel<BrandModel>();
                return View(model);
            }
        }

        [HttpPost]
        public IActionResult Edit(BrandModel model, bool continueEditing)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageBrands))
                return HttpUnauthorized();

            var brand = _brandService.GetById(model.Id);
            if (brand == null || brand.Deleted)
                //No brand found with the specified id
                return RedirectToAction("List");

            if (ModelState.IsValid)
            {
                int prevPictureId = brand.PictureId;
                brand = model.ToEntity(brand);
                brand.UpdateTime = DateTime.Now;
                _brandService.Update(brand);
                //delete an old picture (if deleted or updated)
                if (prevPictureId > 0 && prevPictureId != brand.PictureId)
                {
                    var prevPicture = _pictureService.GetPictureById(prevPictureId);
                    if (prevPicture != null)
                        _pictureService.DeletePicture(prevPicture);
                }
                //activity log
                _activityLogService.InsertActivity("EditBrand", _localizationService.GetResource("ActivityLog.EditBrand"), brand.Name);

                return Json(new { success = 1 });
            }
            else
            {
                brand = model.ToEntity<Brand>();
                brand.CreateTime = DateTime.Now;
                brand.UpdateTime = DateTime.Now;
                _brandService.Insert(brand);
                //activity log
                _activityLogService.InsertActivity("AddNewBrand", _localizationService.GetResource("ActivityLog.AddNewBrand"), brand.Name);

                return Json(new { success = 1 });
            }
        }

        [HttpPost]
        public IActionResult Published(CheckboxModel checkbox)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageCatalog))
                return HttpUnauthorized();

            var brand = _brandService.GetById(checkbox.Id);
            if (brand == null)
                return Json(new { error = 1 });

            if (checkbox.Checked)
                brand.Published = true;
            else
                brand.Published = false;
            _brandService.Update(brand);

            return Json(new { success = 1 });
        }

        [HttpPost]
        public IActionResult Delete(int id)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageBrands))
                return HttpUnauthorized();

            var brand = _brandService.GetById(id);
            if (brand == null)
                //No brand found with the specified id
                return RedirectToAction("List");

            _brandService.Delete(brand);

            //activity log
            _activityLogService.InsertActivity("DeleteBrand", _localizationService.GetResource("ActivityLog.DeleteBrand"), brand.Name);

            return RedirectToAction("List");
        }

        #endregion

        #region Export / Import

        public IActionResult ExportXml()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageBrands))
                return HttpUnauthorized();

            try
            {
                var brands = _brandService.GetAll(showHidden: true);
                var xml = _exportManager.ExportBrandsToXml(brands);
                return File(Encoding.UTF8.GetBytes(xml), "application/xml", "brands.xml");
            }
            catch (Exception exc)
            {
                return RedirectToAction("List");
            }
        }

        public IActionResult ExportXlsx()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageBrands))
                return HttpUnauthorized();

            try
            {
                var bytes = _exportManager.ExportBrandsToXlsx(_brandService.GetAll(showHidden: true).Where(p => !p.Deleted));

                return File(bytes, "text/xls", "brands.xlsx");
            }
            catch (Exception exc)
            {
                return RedirectToAction("List");
            }
        }

        [HttpPost]
        public IActionResult ImportFromXlsx(IFormFile importexcelfile)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageBrands))
                return HttpUnauthorized();

            try
            {
                if (importexcelfile != null && importexcelfile.Length > 0)
                {
                    _importManager.ImportBrandsFromXlsx(importexcelfile.OpenReadStream());
                }
                else
                {
                    return RedirectToAction("List");
                }
                return RedirectToAction("List");
            }
            catch (Exception exc)
            {
                return RedirectToAction("List");
            }
        }

        #endregion

    }
}
